package session.TX;

import java.util.Calendar;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import javax.ejb.Stateless;
import entity.*;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.Query;

@Stateless
public class TransactionManagerSB implements TransactionManagerSBRemote {

    @PersistenceContext
    EntityManager em;
    private TransactionEntry tranEntity;
    private PurchasedItem_Regular itemEntity;

    public TransactionManagerSB() { //no-arg constructor
    }

    @Override
    public void createTransactionEntry(
            Calendar time_stamp,
            String customerEmail,
            Integer loyaltyPointsAwarded,
            Double subtotal,
            List<PurchasedItem> items) {
        
        //Find the customer
        Query q = em.createQuery("SELECT c from Users c where c.email = :paramCustomerEmail ");
        q.setParameter("paramCustomerEmail", customerEmail);
        
        List list = q.getResultList();
        if (list.isEmpty()) {
            System.out.println(">>> TransactionManagerBean: user not found");
            return;
        }
        
        
        
        tranEntity = new TransactionEntry();

        //persist the purchase items into the database
        for (PurchasedItem p_item : items) {
            em.persist(p_item);
        }

        tranEntity.setTime_stamp(time_stamp);
        tranEntity.setCustomerEmail(customerEmail);
        tranEntity.setLoyaltyPointsAwarded(loyaltyPointsAwarded);
        tranEntity.setSubtotal(subtotal);
        tranEntity.setItems(items);

        em.persist(tranEntity);
        
        
        //Update the most recent transaction and the loyalty points for the customer

        
        Users customer = (Users)list.get(0); 
        //Award loyalty Points
        Integer points = customer.getLoyaltypoint() + loyaltyPointsAwarded; 
        customer.setMostRecentTransactionDate(time_stamp.getTime());
        customer.setLoyaltypoint(points);
        
        
        //Update the expiry date of his loyalty points (5 years after most recent transaction)
        Calendar expiryDate = time_stamp;
        expiryDate.add(Calendar.YEAR, 5);
        customer.setExpirydate(expiryDate.getTime());
        
                    
        //add the transaction into the user's list of transactions
        List<TransactionEntry> temp = customer.getList_transactionEntry();
        temp.add(tranEntity);
        customer.setList_transactionEntry(temp);
                    
        
        
        em.flush();
        
        System.out.println(">>> TransactionManagerBean: Created Transaction Entry");
    }//-------------------------------------------------------------------------------------------------------

    @Override
    public PurchasedItem createPurchasedItem_Regular(
            Calendar time_stamp,
            String customerEmail,
            String seller,
            String item_name,
            Long item_id,
            Double item_total_price,
            String buyer_country,
            Integer buyer_age,
            Long outlet_id, Integer quantity, String outletName, Long stakeholderId, Long customerId) {

        itemEntity = new PurchasedItem_Regular();

        itemEntity.setTime_stamp(time_stamp);
        itemEntity.setCustomerEmail(customerEmail);
        itemEntity.setSeller(seller);
        itemEntity.setItem_name(item_name);
        itemEntity.setItem_id(item_id);
        itemEntity.setSubtotal(item_total_price);
        itemEntity.setBuyer_country(buyer_country);
        itemEntity.setBuyer_age(buyer_age);
        itemEntity.setOutlet_id(outlet_id);
        itemEntity.setQuantity(quantity);
        itemEntity.setOutlet_name(outletName);
        itemEntity.setStakeholderId(stakeholderId);
        itemEntity.setCustomerId(customerId);

        return itemEntity;
        //Note, the item is NOT persisted in this method. The createTransactionEntry() method above will call this method
        //to make the item and then persist it there.

    }//-------------------------------------------------------------------------------------------------------

    //Xiaodi added on 19:22, 18/10/2011
    public PurchasedItem createPurchasedItem_GroupOn(Long item_id,
            String itemName,
            String itemDesc,
            Calendar time_stamp,
            String customerEmail,
            String seller,
            Long customerId,
            Integer qty,
            Double subtotal) {
        PurchasedItem_GroupOn pbItem = new PurchasedItem_GroupOn();
        pbItem.setItem_id(item_id);
        pbItem.setItem_name(itemName);
        pbItem.setItem_description(itemDesc);
        pbItem.setTime_stamp(time_stamp);
        pbItem.setCustomerEmail(customerEmail);
        pbItem.setSeller(seller);
        pbItem.setCustomerId(customerId);
        pbItem.setQuantity(qty);
        pbItem.setSubtotal(subtotal);
        pbItem.setDealIsOff(false);
        pbItem.setNoRedeemed(0);
        return pbItem;
        //Note, the item is NOT persisted in this method. The createTransactionEntry() method above will call this method
        //to make the item and then persist it there.
    }
    
    
    // Method to get PurchasedItem_Regular
    public List<PurchasedItem_Regular> retrievePurchasedItemRegular(String customerEmail, Long outletID, boolean filterByOutlet){
        List<PurchasedItem_Regular> returnList = new ArrayList<PurchasedItem_Regular>();
   
        String query = "SELECT c from PurchasedItem_Regular c where c.customerEmail = '" + customerEmail + "'";
        if(filterByOutlet){
            query = query + " AND c.outlet_id = " + outletID;
        }
        
        Query q = em.createQuery(query);
        
        for(Object o: q.getResultList()){       
            PurchasedItem_Regular item = (PurchasedItem_Regular)o;
            
            if (!item.getRedeemed()){
                returnList.add(item);  
            }       
        }
        
        return returnList;
    }   
    
 
    public List<PurchasedItem_GroupOn> retrievePurchasedItemGroupon(String customerEmail, String stakeholderName, boolean filterByStakeholder){
        List<PurchasedItem_GroupOn> returnList = new ArrayList<PurchasedItem_GroupOn>();
   
        String query = "SELECT c from PurchasedItem_GroupOn c where c.customerEmail = '" + customerEmail + "'";
        if(filterByStakeholder){
            query = query + " AND c.seller = '" + stakeholderName + "'";
        }
        
        Query q = em.createQuery(query);
        
        for(Object o: q.getResultList()){       
            PurchasedItem_GroupOn item = (PurchasedItem_GroupOn)o;
            
            if (!item.getRedeemed() && !item.isDealIsOff()){
                returnList.add(item);  
            }       
        }
        
        return returnList;
    }
    
    public void redeemPurchases(Long id){
        PurchasedItem_Regular purchasedItem=null;
        String query = "SELECT c from PurchasedItem_Regular c where c.id = '" + id + "'";
        Query q = em.createQuery(query);
        for(Object o: q.getResultList()){
            purchasedItem = (PurchasedItem_Regular)o;
        }
        purchasedItem.setRedeemed(true);
    }
    
    public boolean redeemGroupon(Long id, int qty){
        PurchasedItem_GroupOn purchaseGroupon=null;
        String query = "SELECT c FROM PurchasedItem_GroupOn c WHERE c.id = " + id;
        Query q = em.createQuery(query);
        for(Object o: q.getResultList()){
            purchaseGroupon = (PurchasedItem_GroupOn)o;
        }
        if((qty + purchaseGroupon.getNoRedeemed()) > purchaseGroupon.getQuantity()){
            System.out.println(">>> ERROR: Amount to redeem exceeds available coupons left");
            return false;
        }else if((qty + purchaseGroupon.getNoRedeemed()) == purchaseGroupon.getQuantity()){
            purchaseGroupon.setNoRedeemed(qty);
            purchaseGroupon.setRedeemed(true);
            System.out.println(">>> SUCCESS: The group deal item is redeemed. No coupons left for this deal");
            return true;
        }else{
            int x = purchaseGroupon.getNoRedeemed();
            purchaseGroupon.setNoRedeemed(qty + x);
            System.out.println(">>> SUCCESS: The group deal item is redeemed.");
            return true;
        }
    }   
}